# encoding: utf-8
# module main
import json
from typing import Optional

import databases
from fastapi import WebSocket, WebSocketDisconnect
import datetime

from sqlalchemy import text

import utils
from app_config import create_app
from apps.users.models import UserInfoSchema
from config.models import User, UserChatRecord, WatchStatistics
from config.settings import DATABASE_URL
from config.typing import UserChatRecordTyping, WatchStatisticsTyping, WatchMsgTyping

app = create_app()
database = databases.Database(DATABASE_URL)
members = []
messages = []


@app.on_event("startup")
async def startup():
    await database.connect()


@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()


@app.post('/user/create_user')
async def create_user(user: UserInfoSchema):
    _user = {"name": user.name, "member": user.member}
    query = User.insert().values(**_user)
    last_record_id = await database.execute(query)
    return {"id": last_record_id}


@app.websocket("/socket/room_chat/")
async def chat_room(member: WebSocket, userId: int, userName: str):
    await member.accept()
    members.append(member)
    [await member.send_text("用户{}进入了聊天室".format(userName)) for member in members]
    try:
        while True:
            msg = await member.receive_text()
            [await member.send_text("{}:{}".format(userName, msg)) for member in members]
            try:
                createDate = utils.datetime2string()
                query = UserChatRecord.insert().values(userId=userId, userName=userName,
                                                       content=msg, createDate=createDate)
                user_chat_record = await database.execute(query)
            except Exception as e:
                pass
    except WebSocketDisconnect:
        members.remove(member)
        leave_msg = "用户{}离开房间".format(userName)
        [await member.send_text("{}".format(leave_msg)) for member in members]


@app.websocket("/socket/watch_statistics/")
async def watch_statistics(member: WebSocket, liveId: int, userId: int, enterpriseId: int, watchId: Optional[int]=None):
    user_watch = dict()
    await member.accept()
    startDate = utils.datetime2string()
    try:
        while True:
            recive_msg = await member.receive_text()
            msg = json.loads(recive_msg)
            type = msg.get("type")
            msg_message = msg.get("msg")
            msg_type = msg.get("msg_type")

            if type == "live":
                if msg_type == "start":
                    try:
                        inviter = msg_message.get("inviter", None)
                        agentUser = msg_message.get("agentUser", None)
                        ip = msg_message.get("ip", None)
                        instance = {
                            "liveId": liveId,
                            "enterpriseId": enterpriseId,
                            "userId": userId,
                            "inviter": inviter,
                            "agentUser": agentUser,
                            "ip": ip,
                            "startDate": startDate,
                            "createDate": startDate,
                            "updateDate": startDate
                        }
                        # query = WatchStatistics.insert().values(**instance)
                        # watch = await database.execute(query)
                        user_watch.update(instance)
                        await member.send_text("用户{}进入了直播间".format(userId))
                    except Exception as e:
                        pass
    except WebSocketDisconnect:
        endDate = utils.datetime2string()
        startDate = user_watch.get("startDate")
        try:
            strp_endDate = datetime.datetime.strptime(endDate, '%Y-%m-%d %H:%M:%S')
            strp_startDate = datetime.datetime.strptime(startDate, '%Y-%m-%d %H:%M:%S')
            duration = (strp_endDate - strp_startDate).total_seconds()
            user_watch.update({"endDate": endDate, "duration": duration})
            query = WatchStatistics.insert().values(**user_watch)
            watch = await database.execute(query)
        except Exception as e:
                pass
        # if watchId:
        #     try:
        #         endDate = datetime.datetime.now()
        #         instance = WatchStatistics.select(text("startDate")).where(WatchStatistics.c.id == watchId)
        #         start_date = await database.fetch_one(instance)
        #         new_start_date = start_date.startDate
        #         duration = (endDate - new_start_date).total_seconds()
        #         str_endDate = utils.datetime2string()
        #         query = WatchStatistics.update().where(WatchStatistics.c.id == watchId).values(endDate=str_endDate, duration=duration, updateDate=str_endDate)
        #         watch = await database.execute(query)
        #     except Exception as e:
        #             pass


if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

